package cn.com.zero.web.config.converter;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.core.convert.converter.Converter;

import java.util.Date;

/**
 * @author xiongxj
 * @version 1.0.0
 * @Description 当 Controller 中的参数为 Date 类型时，
 * 系统不能直接将传入的字符串类型参数转换成日期，
 * 通过本类将传入的参数转换成日期格式
 * @createTime 2023/3/19 15:45
 */
public class StringToDateConverter implements Converter<String, Date> {
    private static final String DATA_FORMAT = "yyyy-MM-dd";
    private static final String DATA_FORMAT2 = "yyyy/MM/dd";
    private static final String TIME_FORMAT = " HH:mm:ss";
    private static final String TIME_FORMAT2 = " HH:mm";
    private static final String TIME_STAMP_FORMAT = "^\\d+$";
    private static final String SEPARATORS0 = "-";
    private static final String SEPARATORS1 = "/";
    private static final String SEPARATORS2 = ":";

    @Override
    public Date convert(String value) {
        if (StrUtil.isEmpty(value)) {
            return null;
        }
        value = value.trim();
        try {
            // 处理时间戳传值
            if (value.matches(TIME_STAMP_FORMAT)) {
                //时间戳
                Long timestamp = new Long(value);
                return new Date(timestamp);
            }

            // 时间格式
            String pattern;

            if (value.contains(SEPARATORS0)) {
                pattern = DATA_FORMAT;
                if (StrUtil.count(value, SEPARATORS0) == 1) {
                    value += SEPARATORS0 + "01";
                }
            } else if (value.contains(SEPARATORS1)) {
                pattern = DATA_FORMAT2;
                if (StrUtil.count(value, SEPARATORS1) == 1) {
                    value += SEPARATORS1 + "01";
                }
            } else {
                throw new RuntimeException(String.format("parser %s to Date fail", value));
            }

            if (value.contains(SEPARATORS2)) {
                int count = countStringShowTimes(value, SEPARATORS2);
                if (count == 1) {
                    pattern += TIME_FORMAT2;
                } else if (count == 2) {
                    pattern += TIME_FORMAT;
                }
            }
            return DateUtil.parse(value, pattern);
        } catch (Exception e) {
            throw new RuntimeException(String.format("parser %s to Date fail", value));
        }
    }

    /**
     * 统计字符串中指定字符串的出现次数
     *
     * @param baseStr   原字符串
     * @param targetStr 待查找串
     * @return int 次数
     */
    private int countStringShowTimes(String baseStr, String targetStr) {
        //获取字符串的长度
        int baseStrLen = baseStr.length();

        //把需要查找的元素都替换为空
        String afterStr = baseStr.replaceAll(targetStr, "");

        //获取替换后的字符串的长度
        int afterStrLen = afterStr.length();

        //要被查找的元素的个数=原长度-替换后的长度
        return baseStrLen - afterStrLen;
    }
}
